import os
from django.shortcuts import render
from django.views.decorators.http import require_POST, require_GET
from apps.news.models import News, NewsCategory
from apps.xfzauth.models import User
from utils import restful
from .forms import EditNewsCategoryForm, WriteNewsForm,AddBannerForm,EditBannerForm,EditNewsForm
from django.views.generic import View
from django.conf import settings
from django.core.paginator import  Paginator
from datetime import datetime
from django.utils.timezone import make_aware
from urllib import parse
import qiniu
from apps.news.models import Banner
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import permission_required
from apps.news.serializers import BannerSerializer
from django.contrib.admin.views.decorators import staff_member_required
# Create your views here.
@staff_member_required(login_url='/news')
def index(request):
    return render(request, 'cms/index.html')

    # 添加文章分类
@require_POST
@permission_required(perm='news.add_newscategory')
def add_news_category(request):
    name = request.POST.get('name')
    exists = NewsCategory.objects.filter(name=name).exists()
    if not exists:
        NewsCategory.objects.create(name=name)
        return restful.ok()
    else:
        return restful.params_error(message="该分类已经存在")

    # 展示所有的分类
@require_GET
@permission_required(perm='news.add_newscategory')
def news_category(request):
    categories = NewsCategory.objects.all()
    context = {
        'categories': categories
    }
    return render(request, 'news/news_category.html', context=context)

    # 编辑分类
@require_POST
@permission_required(perm='news.change_newscategory')
def edit_news_category(request):
    form = EditNewsCategoryForm(request.POST)
    if form.is_valid():
        pk = form.cleaned_data.get('pk')
        name = form.cleaned_data.get('name')
        try:
            NewsCategory.objects.filter(pk=pk).update(name=name)
            return restful.ok()
        except:
            return restful.params_error(message="该分类不存在")
    return restful.params_error(message=form.get_errors())

    # 删除分类
@require_POST
@permission_required(perm='news.delete_newscategory')
def delete_news_category(request):
    pk = request.POST.get('pk')
    try:
        NewsCategory.objects.filter(pk=pk).delete()
        return restful.ok()
    except:
        return restful.params_error(message="该分类不存在")


@method_decorator(permission_required(perm='news.change_news',login_url='/news'),name='dispatch')
class NewsListView(View):
    #Paginator常用属性和方法：
    # 1. count：总共有多少条数据。
    # 2. num_pages：总共有多少页。
    # 3. page_range：页面的区间。比如有三页，那么就range(1,4)。
    # Page常用属性和方法：
    # 1. has_next：是否还有下一页。
    # 2. has_previous：是否还有上一页。
    # 3. next_page_number：下一页的页码。
    # 4. previous_page_number：上一页的页码。
    # 5. number：当前页。
    # 6. start_index：当前这一页的第一条数据的索引值。
    # 7. end_index：当前这一页的最后一条数据的索引值。

    def get(self, request):
        # request.GET：获取出来的所有数据，都是字符串类型
        page = int(request.GET.get('p', 1))
        start = request.GET.get('start')
        end = request.GET.get('end')
        title = request.GET.get('title')
        # request.GET.get(参数,默认值)
        # 这个默认值是只有这个参数没有传递的时候才会使用
        # 如果传递了，但是是一个空的字符串，那么也不会使用默认值
        category_id = int(request.GET.get('category', 0) or 0)

        newses = News.objects.select_related('category', 'author')

        if start or end:
            if start:
                start_date = datetime.strptime(start, '%Y/%m/%d')
            else:
                start_date = datetime(year=2019, month=7, day=19)
            if end:
                end_date = datetime.strptime(end, '%Y/%m/%d')
            else:
                end_date = datetime.today()
            newses = newses.filter(pub_time__range=(make_aware(start_date), make_aware(end_date)))

        if title:
            newses = newses.filter(title__icontains=title)

        if category_id:
            newses = newses.filter(category=category_id)

        paginator = Paginator(newses, 2) # 实例化paginator 对象
        page_obj = paginator.page(page) #当前页的对象

        context_data = self.get_pagination_data(paginator, page_obj)

        context = {
            'categories': NewsCategory.objects.all(),
            'newses': page_obj.object_list,#当前页的数据
            'page_obj': page_obj,
            'paginator': paginator,
            'start': start,
            'end': end,
            'title': title,
            'category_id': category_id,
            'url_query': '&' + parse.urlencode({
                'start': start or '',
                'end': end or '',
                'title': title or '',
                'category': category_id or ''
            }) #将字典url
        }

        print('=' * 30)
        print(context['url_query'])
        print('=' * 30)

        context.update(context_data)

        return render(request, 'cms/news_list.html', context=context)


    def get_pagination_data(self,paginator,page_obj,arround_count=2):
        current_page = page_obj.number #当前页
        num_pages = paginator.num_pages #总共多少页面
        left_has_more = False # 左侧是否还有...
        right_has_more = False #头边是否还有...

        if current_page <= arround_count+2:
            left_pages = range(1,current_page) #range(1,4)
            #1234
        else:
            left_has_more = True
            #1...34567...
            left_pages = range(current_page-arround_count,current_page)

        if current_page >= num_pages-arround_count-1:
            right_pages = range(current_page+1,num_pages+1)
        #1234567891011
        else:
            right_has_more = True
            right_pages = range(current_page + 1, current_page+arround_count + 1)


        return  {
            'left_pages':left_pages,#当前页左边的页码
            'right_pages':right_pages,#当前页右边的页码
            'current_page':current_page,
            'left_has_more':left_has_more,
            'right_has_more':right_has_more,
            'num_pages':num_pages

        }

@method_decorator(permission_required(perm='news.add_news',login_url='/news'),name='dispatch')
class WriteNewsView(View):
    def get(self, request):
        categories = NewsCategory.objects.all()
        context = {
            'categories': categories
        }
        return render(request, 'cms/write_news.html', context=context)

    def post(self, request):
        forms = WriteNewsForm(request.POST)
        if forms.is_valid():
            title = forms.cleaned_data.get('title')
            desc = forms.cleaned_data.get('desc')
            thumbnail = forms.cleaned_data.get('thumbnail')
            content = forms.cleaned_data.get('content')
            category_id = forms.cleaned_data.get('category')
            category = NewsCategory.objects.get(pk=category_id)
            News.objects.create(title=title, desc=desc, thumbnail=thumbnail, content=content, category=category,
                                author=request.user)
            return restful.ok()
        else:
            return restful.params_error(message=forms.get_errors())

    # 文件上传
@require_POST
def upload_file(request):
    file = request.FILES.get('file')
    name = file.name
    print(name)
    with open(os.path.join(settings.MEDIA_ROOT, name), 'wb') as fp:
        for chunk in file.chunks():
            fp.write(chunk)
    url = request.build_absolute_uri(settings.MEDIA_URL + name)

    return restful.result(data={'url': url})

@require_GET  # 这个方法主要是用来 将 accesskey secretkey 提交过去
# 给你返回token
def qntoken(request):
    access_key = settings.QINIU_ACCESS_KEY
    secret_key = settings.QINIU_SECRET_KEY

    bucket = settings.QINIU_BUCKET_NAME
    q = qiniu.Auth(access_key,secret_key)

    token = q.upload_token(bucket)
    print(token)

    return restful.result(data={"token":token})


def banners(request):
    return render(request,'cms/banners.html')



def banner_list(request):
    banners = Banner.objects.all()
    serialize = BannerSerializer(banners,many=True)
    return restful.result(data=serialize.data)


def add_banner(request):
    form = AddBannerForm(request.POST)
    if form.is_valid():
        priority = form.cleaned_data.get('priority')
        image_url = form.cleaned_data.get('image_url')
        link_to = form.cleaned_data.get('link_to')
        banner = Banner.objects.create(priority=priority,image_url=image_url,link_to=link_to)
        return restful.result(data={"banner_id":banner.pk})
    else:
        return restful.params_error(message=form.get_errors())


def delete_banner(request):
    banner_id = request.POST.get('banner_id')
    Banner.objects.filter(pk=banner_id).delete()
    return restful.ok()



def edit_banner(request):
    form = EditBannerForm(request.POST)
    if form.is_valid():
        pk = form.cleaned_data.get('pk')
        image_url = form.cleaned_data.get('image_url')
        link_to = form.cleaned_data.get('link_to')
        priority = form.cleaned_data.get('priority')
        Banner.objects.filter(pk=pk).update(image_url=image_url,link_to=link_to,priority=priority)
        return restful.ok()
    else:
        return restful.params_error(message=form.get_errors())
